from flask import Flask, request, jsonify
from models import db, Ticket
import os
from datetime import datetime
from dotenv import load_dotenv, dotenv_values

# 直接从指定路径的.env文件读取配置
print("正在从指定路径加载.env文件配置...")
# 使用相对路径指向当前项目目录下的.env文件（位于1102TicketingSystem目录）
env_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), '.env')

# 检查文件是否存在
if os.path.exists(env_path):
    print(f"找到.env文件: {env_path}")
    # 使用dotenv_values直接读取文件内容
    config = dotenv_values(env_path)
    print('config', config)
    
    # 直接从配置中获取数据库URL
    database_url = config.get('DATABASE_URL', 'postgresql://postgres:password@localhost:15432/ticketing_system')
    config_source = '自定义配置（从.env文件）' if config.get('DATABASE_URL') else '默认配置'
else:
    print(f"警告: .env文件不存在: {env_path}")
    print("将使用默认数据库配置")
    database_url = 'postgresql://postgres:password@localhost:15432/ticketing_system'
    config_source = '默认配置（未找到.env文件）'

# 创建Flask应用
app = Flask(__name__)

# 配置数据库 - 只支持 PostgreSQL
app.config['SQLALCHEMY_DATABASE_URI'] = database_url
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

# 显示配置信息（隐藏密码）
hidden_password_url = database_url.replace(database_url.split('@')[0].split(':')[1][2:], '****')
print(f"当前数据库配置: {hidden_password_url}")
print(f"配置来源: {config_source}")

# 数据库可用性标记（初始为不可用）
db_available = False

# 初始化数据库
db.init_app(app)

# 数据库表检查函数 - 只在表不存在时创建，不会重置数据
def check_database():
    print("开始检查数据库连接...")
    try:
        # 验证数据库 URL 是否为 PostgreSQL
        if not app.config['SQLALCHEMY_DATABASE_URI'].startswith('postgresql://'):
            print(f"错误: 数据库连接字符串必须是 PostgreSQL 格式")
            print(f"当前值: {app.config['SQLALCHEMY_DATABASE_URI']}")
            print("正确格式: postgresql://user:password@host:port/database")
            return False
        
        # 提示用户配置正确的数据库连接
        if app.config['SQLALCHEMY_DATABASE_URI'] == 'postgresql://postgres:password@localhost:15432/ticketing_system':
            print("警告: 当前使用的是默认数据库连接配置")
            print(f"请在当前项目目录(1102TicketingSystem)下的.env文件中配置正确的 PostgreSQL 连接信息")
            print(f"文件路径: 1102TicketingSystem/.env")
            print("配置格式: DATABASE_URL=postgresql://user:password@host:port/database")
        
        with app.app_context():
            # 检查表是否存在，如果不存在则创建
            db.create_all()
            print("PostgreSQL 数据库表检查完成 - 只创建不存在的表，不会重置现有数据")
            return True
    except Exception as e:
        print(f"PostgreSQL 数据库连接失败: {str(e)}")
        print(f"请检查当前项目目录(1102TicketingSystem)下的.env文件中的数据库连接配置")
        print("以及数据库服务是否可用")
        return False

# 启动时进行数据库检查
db_available = check_database()

# 1. 创建工单
@app.route('/api/tickets', methods=['POST'])
def create_ticket():
    # 检查数据库是否可用
    if not db_available:
        return jsonify({'error': '数据库服务不可用，请稍后再试'}), 503
    
    try:
        data = request.get_json()
        
        # 验证必要字段
        if not data or not all(k in data for k in ['ticket_type', 'title', 'description']):
            return jsonify({'error': '缺少必要字段'}), 400
        
        # 验证工单类型
        valid_types = ['咨询', '故障', '反馈']
        if data['ticket_type'] not in valid_types:
            return jsonify({'error': '工单类型无效，必须是咨询、故障或反馈'}), 400
        
        # 创建工单
        new_ticket = Ticket(
            ticket_type=data['ticket_type'],
            title=data['title'],
            description=data['description'],
            status='新建'
        )
        
        db.session.add(new_ticket)
        db.session.commit()
        
        return jsonify({'ticket_id': new_ticket.id}), 201
    
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

# 2. 更新工单
@app.route('/api/tickets/<int:ticket_id>', methods=['PUT'])
def update_ticket(ticket_id):
    # 检查数据库是否可用
    if not db_available:
        return jsonify({'error': '数据库服务不可用，请稍后再试'}), 503
    
    try:
        # 查找未删除的工单
        ticket = Ticket.query.filter_by(id=ticket_id, deleted_at=None).first()
        if not ticket:
            return jsonify({'error': '工单不存在'}), 404
        
        data = request.get_json()
        
        # 更新字段
        if 'status' in data:
            ticket.status = data['status']
        if 'title' in data:
            ticket.title = data['title']
        if 'description' in data:
            ticket.description = data['description']
        if 'ticket_type' in data:
            # 验证工单类型
            valid_types = ['咨询', '故障', '反馈']
            if data['ticket_type'] not in valid_types:
                return jsonify({'error': '工单类型无效，必须是咨询、故障或反馈'}), 400
            ticket.ticket_type = data['ticket_type']
        
        db.session.commit()
        return jsonify({'success': True}), 200
    
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

# 3. 删除工单（软删除）
@app.route('/api/tickets/<int:ticket_id>', methods=['DELETE'])
def delete_ticket(ticket_id):
    # 检查数据库是否可用
    if not db_available:
        return jsonify({'error': '数据库服务不可用，请稍后再试'}), 503
    
    try:
        # 查找未删除的工单
        ticket = Ticket.query.filter_by(id=ticket_id, deleted_at=None).first()
        if not ticket:
            return jsonify({'error': '工单不存在'}), 404
        
        # 软删除
        ticket.deleted_at = datetime.utcnow()
        db.session.commit()
        
        return jsonify({'success': True}), 200
    
    except Exception as e:
        db.session.rollback()
        return jsonify({'error': str(e)}), 500

# 4. 获取工单列表
@app.route('/api/tickets', methods=['GET'])
def get_tickets():
    # 检查数据库是否可用
    if not db_available:
        return jsonify({'error': '数据库服务不可用，请稍后再试'}), 503
    
    try:
        # 获取查询参数
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        ticket_type = request.args.get('ticket_type')
        status = request.args.get('status')
        order_by = request.args.get('order_by', 'created_at')
        sort = request.args.get('sort', 'desc')
        
        # 构建查询
        query = Ticket.query.filter_by(deleted_at=None)
        
        # 应用筛选条件
        if ticket_type:
            # 验证工单类型
            valid_types = ['咨询', '故障', '反馈']
            if ticket_type in valid_types:
                query = query.filter_by(ticket_type=ticket_type)
            else:
                return jsonify({'error': '工单类型无效，必须是咨询、故障或反馈'}), 400
        
        if status:
            query = query.filter_by(status=status)
        
        # 应用排序
        if order_by in ['created_at', 'updated_at', 'id']:
            order_column = getattr(Ticket, order_by)
            if sort.lower() == 'asc':
                query = query.order_by(order_column.asc())
            else:
                query = query.order_by(order_column.desc())
        
        # 分页
        pagination = query.paginate(page=page, per_page=per_page, error_out=False)
        
        # 构建响应
        tickets = [ticket.to_dict() for ticket in pagination.items]
        
        return jsonify({
            'tickets': tickets,
            'total': pagination.total,
            'pages': pagination.pages,
            'current_page': page,
            'per_page': per_page
        }), 200
    
    except Exception as e:
        return jsonify({'error': str(e)}), 500

# 健康检查接口
@app.route('/health', methods=['GET'])
def health_check():
    return jsonify({'status': 'healthy'}), 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=False)